 package com.superpai.view.download; 

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import com.superpai.utils.BitmapUtils;

/**
 * @author 
 * @date 2011-7-7
 * @Description
 * @version V1.0 
 */
public class ImageLoadAdapter extends BaseAdapter implements OnDownLoadFileListener{

	private Context mContext;
	
	/** 适配器的item数量 **/
	private int mDataCount;
	
	//监听器
	private ILoadImageListener mLoadListener;
	
	//下载器
	private ImageDownloader mDownloader;
	
	//缓存加载器
	private ImageDownloader mCacheLoader;
	
	//view缓存
	protected HashMap<Integer, View> mViewMap;
	
	//下载任务的备份
	protected HashMap<Integer, DownloadObj> mDownloadTaskMap;
	
	//跟踪imageView实例出来的数量
	private int mLoadImageCount;

	private int mBoundItem;
	
	//同时存在的imageView最大数量
	private int mMaxCache = 20;
	
	private HashMap<String, Boolean> mDownloadFileMap;
	
	protected boolean mIsDestroy;
	
	public ImageLoadAdapter(Context context){
		
		mContext = context;
		
		mIsDestroy = false;
		
		mViewMap = new HashMap<Integer, View>();
		mDownloadTaskMap = new HashMap<Integer, DownloadObj>();
		
//		//if(MainActivity.instance!=null){
//			mDownloadFileMap = MainActivity.instance.shareFileCacheMap();
//		}else{
			mDownloadFileMap = new HashMap<String, Boolean>();
//		}
		
		mDownloader = new ImageDownloader(mContext, mDownloadFileMap);
		mDownloader.setListener(this);
		
		mCacheLoader = new ImageDownloader(mContext, mDownloadFileMap);
		mCacheLoader.setListener(this); 
	}
	
	@Override
	public int getCount() {
		
		return mDataCount;
	}

	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		
		if(mViewMap.containsKey(position)){
			//如果View以加载则置顶该位置的下载任务
			downloadTask(position);
			View view = mViewMap.get(position);
			
			return view;
		}else {
			if(mLoadListener!=null){
				
				View defaultView = mLoadListener.getCacheDefaultView(position);
				
				mViewMap.put(position, defaultView);
				
				//下载图片为空则设置空图片,否则添加下载任务到下载队列
				addDownLoadTask(position);
				
				mLoadImageCount++;
				
				checkBoundVM(position);
				
				return defaultView;
			}
			else {
				Log.v("DownLoad", "你需要为ImageLoadAdapter设置监听器");
				return null;
			}
		}
	}

	public void downloadTask(int position){
		DownloadObj downloadObj = mDownloadTaskMap.get(position);
		if(downloadObj!=null){
			
			int tagetState = downloadObj.getState();
			//等待下载或已释放的任务将被加入并置顶下载队列
			if(tagetState==DownloadObj.STATE_WAIT || tagetState==DownloadObj.STATE_RECYLE){
				//下载任务置顶
				if(mDownloadFileMap.containsKey(downloadObj.getFileName())){
					//如果已下载过则放入缓存加载队列独立加载缓存数据
					mCacheLoader.addDownLoadTask2Top(downloadObj);
					mCacheLoader.startDownload();
				}else{
					mDownloader.addDownLoadTask2Top(downloadObj);
					Log.v("DownLoad", "(getView)置顶 DownLoad：" + downloadObj.getFileName());
					mDownloader.startDownload();
				}
			}else{
				Log.v("LoadDebug", "(getView)taskState:"+ tagetState + "|Position:" + position + "|File:" + downloadObj.getFileName());
			}
		}
	}
	/**
	 * 检测是否超出最大
	 *
	 * @param position
	 * @return 
	 */
	private void checkBoundVM(int position){
		
		if(position!=0 && mLoadImageCount>mMaxCache){
			int maxPosition = position + mMaxCache;
			int minPosition = position - mMaxCache;
			if(maxPosition<getCount()&& mViewMap.containsKey(maxPosition)){
				releaseView(maxPosition);
			}else
			if(minPosition>=0&& mViewMap.containsKey(minPosition)){
				releaseView(minPosition);
			}
		}
	}

	/**
	 * 释放内存
	 *
	 * @param position
	 * @return 
	 */
	private void releaseView(int position){
		
		mLoadImageCount--;
		
		DownloadObj downTask = mDownloadTaskMap.get(position);
		
		if(downTask!=null){
			
			//任务在队列则移出
			if(downTask.getState()==DownloadObj.STATE_DOWNLOADING){
				mDownloader.removeLoadTask(downTask);
				mCacheLoader.removeLoadTask(downTask);
			}
		
			//清除与之对应任务中的Bitmap
			Bitmap bmp = downTask.getDownBitmap();
			if(bmp!=null){
				View cacheView = mViewMap.get(position);
				if(cacheView!=null){
					mLoadListener.processDefaultState(cacheView, position);
				}
				
				bmp.recycle();
				System.gc();
				downTask.setDownBitmap(null);
			}
			if(downTask.getState()==DownloadObj.STATE_USE)
				downTask.setState(DownloadObj.STATE_RECYLE);
		}
		//清除imageView
		mViewMap.remove(position);
	}
	
	/**
	 * 添加下载任务，如果下载器不在运行则启动下载器
	 *
	 * @param position
	 * @return 
	 */
	private void addDownLoadTask(int position){
		
		DownloadObj downTask = mDownloadTaskMap.get(position);
		
		if(downTask==null){
			
			String fileUrl = mLoadListener.getDownloadUrl(position);
			
			int beginIndex = fileUrl.lastIndexOf("/") + 1;
			String fileName = fileUrl.substring(beginIndex).trim();
			
			if(!fileName.equals(""))
			{
				int endIndex = fileName.lastIndexOf(".");
				fileName = fileName.substring(0, endIndex);
				//新建下载任务
				DownloadObj downloadObj = new DownloadObj();
				downloadObj.setDownIndex(position);
				downloadObj.setFileName(fileName);
				downloadObj.setFileUrl(fileUrl);
				
				if(mDownloadFileMap.containsKey(fileName)){
					mCacheLoader.addDownLoadTask(downloadObj);
					mCacheLoader.startDownload();
				}else{
					mDownloader.addDownLoadTask(downloadObj);
					mDownloader.startDownload();
				}

				mDownloadTaskMap.put(position, downloadObj);
				
			}else{
				mLoadListener.processEmptyState(mViewMap.get(position), position);
			}
		}else if(downTask.getState()==DownloadObj.STATE_ERROR){
			//错误图片
			mLoadListener.processErrorState(mViewMap.get(position), position);
		}else {
			//将已有的任务放入下载队列
			mDownloader.addDownLoadTask(downTask);
			mDownloader.startDownload();
		}
	}

	
	/**
	 * 下载器监听到文件
	 *
	 * @param values
	 * @return 
	 */
	@Override
	public void onProcessDownload(Object... values) {

		int result = Integer.parseInt(values[0].toString());
		DownloadObj downloadObj = (DownloadObj)values[1];
		
		int position = downloadObj.getDownIndex();
		View cacheView = mViewMap.get(position);
		
		switch (result) {
			//文件下载未出现异常
			case ImageDownloader.DOWN_IMAGE:
				
				Bitmap bitmap = downloadObj.getDownBitmap();
				//Cache View是否被释放
				if(cacheView!=null){
					if(bitmap!=null)
					{
						//缓存不为空且bitmap不为空
						mLoadListener.processDownloadBmp(cacheView, bitmap, position);
						downloadObj.setState(downloadObj.STATE_USE);
						
					}else {
						//缓存不为空，但是bitmap为空
						
						downloadObj.setState(downloadObj.STATE_ERROR);
						if(cacheView!=null)
							mLoadListener.processErrorState(cacheView, position);
					}
				}else {
					//缓存已被释放
					if(bitmap!=null){
						//图片不为空
						bitmap.recycle();
						System.gc();
						downloadObj.setDownBitmap(null);
					}
					
					downloadObj.setState(downloadObj.STATE_RECYLE);
				}
				break;
			//文件下载出现Exception
			case ImageDownloader.DOWN_ERROR:
				//图片不存在等问题，不再加载
				downloadObj.setState(downloadObj.STATE_ERROR);
				if(cacheView!=null)
					mLoadListener.processErrorState(cacheView, position);
				
				break;
			//文件下载出现TimeOut
			case ImageDownloader.DOWN_AGAIN:
//				图片获取失败，等待下次再次获取
				if(cacheView!=null)
					mLoadListener.processErrorState(cacheView, position);
				downloadObj.setState(downloadObj.STATE_WAIT);
				break;
			default:
				Log.v("DownLoad", "(onDownLoadFile)Default？: " + downloadObj.getFileName());
				downloadObj.setState(downloadObj.STATE_WAIT);
				break;
		}
	}
	
	/**
	 * 停止连接并将所有Task对象中的Bitmap释放
	 * @return void
	 * @throws
	 */
	public void releaseViewAndBmp(){
		//清空View
		mViewMap.clear();
		
		//回收Bimap
		if(mDownloadTaskMap!=null && !mDownloadTaskMap.isEmpty()){
			Iterator<Entry<Integer, DownloadObj>>  iter = mDownloadTaskMap.entrySet().iterator();
			while(iter.hasNext()){
				DownloadObj downObj = (DownloadObj)iter.next().getValue();
				Bitmap bmp = downObj.getDownBitmap();
				if(bmp!=null && !bmp.isRecycled()){
					bmp.recycle();
				}
				downObj.setDownBitmap(null);
				downObj.setState(DownloadObj.STATE_RECYLE);
			}
			System.gc();
		}
		
		mLoadImageCount = 0;
		
		this.notifyDataSetChanged();
	}
	
	public void destroy(){
		
		mIsDestroy = true; 
		stopDownLoad(false);
		releaseViewAndBmp();
		mDownloadTaskMap.clear();
		
		mDownloadTaskMap = null;
		mDownloader = null;
		mCacheLoader = null;
		mDownloadFileMap = null;
	}
	
	/**
	 * 停止下载
	 * @param isShutdown 是否强制停止当前连接
	 * @return void
	 * @throws
	 */
	public void stopDownLoad(boolean isShutdown){
		mDownloader.stopDownLoad(isShutdown);
		mCacheLoader.stopDownLoad(isShutdown);
	}

	/**
	 * 设置图片下载监听器，监听图片文件的下载和处理情况
	 * @param listener
	 * @return void
	 * @throws
	 */
	public void setLoadImageListener(ILoadImageListener listener){
		this.mLoadListener = listener;
	}
	
	/**
	 * 设置Adapter的Item数量
	 * @param count
	 * @return void
	 * @throws
	 */
	public void setDataCount(int count){
		this.mDataCount = count;
	}

	/**
	 * 设置缓存的最大数量
	 * @param maxCachet
	 * @return void
	 * @throws
	 */
	public void setMaxCache(int maxCache) {
		this.mMaxCache = maxCache;
	}
	
	public void setDebugName(String name){
		this.mDownloader.setDebugName(name);
		this.mCacheLoader.setDebugName(name);
	}

	@Override
	public boolean onProcessBytes(DownloadObj downloadObj, byte[] datas) {
		
		int position = downloadObj.getDownIndex();
		View cacheView = mViewMap.get(position);

		if(downloadObj.getDownBitmap()!=null){
			return true;
		}
		
		Bitmap bmp = null;
		//Cache View是否被释放
		if(cacheView!=null){
			if(datas!=null)
			{
				checkBoundVM(mBoundItem);
				if(!mDownloadFileMap.containsKey(downloadObj.getFileName())){
					//处理从网络得到的原始图片
					bmp = mLoadListener.processDownloadBytes(cacheView, datas);
					if(bmp!=null){
						String fileName = downloadObj.getFileName();
						//保存图片到手机存储空间
						BitmapUtils.saveBmpToPng(mContext, bmp, fileName);
						
						mDownloadFileMap.put(fileName, true);
						
						downloadObj.setDownBitmap(bmp);
						return true;
					}
				}else{
					//图片为本地文件,直接处理该图片
					bmp = BitmapFactory.decodeByteArray(datas, 0, datas.length);
					if(bmp!=null){
						downloadObj.setDownBitmap(bmp);
						return true;
					}
				}
			}
		}else{
			//远程已经得到图片，但缓存已被释放
			if(downloadObj.getDownBitmap()!=null){
				downloadObj.getDownBitmap().recycle();
				System.gc();
			}
			downloadObj.setDownBitmap(null);
			return true;
		}
		return false;
	}
	
	public void setBoundItem(int position){
		this.mBoundItem = position;
	}

}
